/**
 * @Project : algorithm-learning
 * @Author : Ruoyu Wang
 * @User : Momenta
 * @DateTime : 2024/4/15 15:49
 */

#include <iostream>
#include <unordered_set>
#include <set>
#include <unordered_map>
#include <map>
#include <queue>
#include <algorithm>

using namespace std;

struct node {
    int a;
    int b;

    node(int a, int b) : a(a), b(b) {}
};

bool cmp(node x, node y) {
    return x.a == y.a ? x.b < y.b : x.a < y.a;
}

struct hashcode {
    size_t operator()(const node &n) const {
        return hash<int>()(n.a) ^ hash<int>()(n.b);
    }
};

size_t hashcode2(const node &x) {
    return hash<int>()(x.a) ^ hash<int>()(x.b);
}

struct equals {
    bool operator()(const node &n1, const node &n2) const {
        return n1.a == n2.a && n1.b == n2.b;
    }
};

bool equals2(const node &n1, const node &n2) {
    return n1.a == n2.a && n1.b == n2.b;
}

int main() {
    node x = {1, 2};
    node y = {2, 3};
    node z = {1, 2};

    /**
    * vector 存放自定义结构体
    */
    vector<node> vec;
    vec.push_back(x);
    vec.push_back(y);
    vec.push_back(z);
    sort(vec.begin(), vec.end(), cmp);
    for (auto e: vec) {
        cout << e.a << " " << e.b << endl;
    }
    cout << endl;

    /**
    * priority_queue 存放自定义结构体
    */
    priority_queue<node, vector<node>, decltype(&cmp)> pq;
    pq.push(x);
    pq.push(y);
    pq.push(z);
    while (!pq.empty()) {
        cout << pq.top().a << " " << pq.top().b << endl;
        pq.pop();
    }
    cout << endl;

    /**
    * set 存放自定义结构体
    */
    set<node, decltype(&cmp)> set2;
    set2.insert(x);
    set2.insert(y);
    set2.insert(z);
    for (auto e: set2) {
        cout << e.a << " " << e.b << endl;
    }
    cout << endl;

    /**
    * map 存放自定义结构体
    */
    map<node, int, decltype(&cmp)> map2;
    map2[x] = 1;
    map2[y] = 2;
    map2[z] = 3;
    for (auto e: map2) {
        cout << e.first.a << " " << e.first.b << " " << e.second << endl;
    }
    cout << endl;

    /**
    * unordered_set 存放自定义结构体
    */
    unordered_set<node, hashcode, equals> set1;
//    unordered_set<node, decltype(&hashcode2), decltype(&equals2)> set1;
    set1.insert(x);
    set1.insert(y);
    set1.insert(z);
    for (auto e: set1) {
        cout << e.a << " " << e.b << endl;
    }
    cout << endl;

    /**
    * unordered_map 存放自定义结构体
    */
    unordered_map<node, int, hashcode, equals> map1;
//    unordered_map<node, int, decltype(&hashcode2), decltype(&equals2)> map1;
    map1[x] = 1;
    map1[y] = 2;
    map1[z] = 3;
    for (auto e: map1) {
        cout << e.first.a << " " << e.first.b << " " << e.second << endl;
    }
    cout << endl;

    return 0;
}